/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#ifndef INCLUDE_SHADER_CURVE
#define INCLUDE_SHADER_CURVE

#include "shader_binding_ID.h"
#include "shader_built_in_functions.h"
#include "shader_tranform.h"


#define DEF_CURVE_SUBDIV 32


struct S_CurvePick {
	vec2 pick_coord;
	vec2 pick_dis;
};

struct S_CurvePoint {
	vec2	L_point;
	vec2	R_point;
	vec2	value;
	uvec2	ID_Color;
	//ѡ������λ��־
	uvec2	Select_Type;
};

#define DEF_CONTORL_POINT_AUTO 0
#define DEF_CONTORL_POINT_FREE 1
#define DEF_CONTORL_POINT_ALGNED 2
#define DEF_CONTORL_POINT_VECTOR 3




#ifdef __cplusplus

#include <向量.h>

// GLSL Type
using uint = unsigned int;
#define in
#define out
#define inout


#define DEF_glsl_Cal_CutCircleRadius Inline float f_glsl_Cal_CutCircleRadius(const S_CurvePoint& cp)
//#define DEF_glsl_CurveSample Inline float f_glsl_CurveSample(float32 sample, const S_CurvePoint& curve, const vec2 cl)


#else

#define Inline

#define DEF_glsl_Cal_CutCircleRadius Inline float f_glsl_Cal_CutCircleRadius(in S_CurvePoint cp)



//void f_curve_point_control(
//	in uint Instance,
//	//S_CurvePoint m_Curve[],
//	out vec2 s_point,
//	out vec2 e_point,
//	out vec2 L_dir,
//	out vec2 R_dir,
//	out vec2 V_dir,
//	out float l_len,
//	out float r_len,
//	out float v_len,
//	out S_CurvePoint s_curve,
//	out S_CurvePoint e_curve,
//	out vec4 color[2],
//	in int num
//) {
//
//	uint s_ID = Instance;
//	uint e_ID = Instance + 1;
//
//	s_curve = m_Curve[s_ID];
//	e_curve = m_Curve[e_ID];
//
//	color[0] = f_glsl_buildColor(s_curve.ID_Color.y);
//	color[1] = f_glsl_buildColor(e_curve.ID_Color.y);
//
//	s_point = s_curve.value;
//	e_point = e_curve.value;
//
//	L_dir = s_curve.R_point - s_point;
//	R_dir = e_curve.L_point - e_point;
//	V_dir = e_curve.L_point - s_curve.R_point;
//
//	l_len = length(L_dir) / num;
//	r_len = length(R_dir) / num;
//	v_len = length(V_dir) / (num * 2);
//
//	L_dir = normalize(L_dir);
//	R_dir = normalize(R_dir);
//	V_dir = normalize(V_dir);
//
//}


//void f_curve_line
vec4 f_curve_point_bind_Left(
	in vec2 s_point,
	in vec2 L_dir,
	in vec2 V_dir,
	in float l_len,
	in float v_len,
	in S_CurvePoint s_curve,
	in float L,
	in uint i
) {
	vec2 s = L_dir * (l_len * i) + s_point;
	vec2 e = V_dir * (v_len * i) + s_curve.R_point;

	e = e - s;
	vec4 vert = vec4(s + e * L, 0, 1);

	return vert;
}


vec4 f_curve_point_bind_Right(
	in vec2 R_dir,
	in vec2 V_dir,
	in float r_len,
	in float v_len,
	in S_CurvePoint s_curve,
	in S_CurvePoint e_curve,
	in float L,
	in uint i
) {

	vec2 s = s_curve.R_point + V_dir * (v_len * (i + 16));
	vec2 e = e_curve.L_point - R_dir * (r_len * i);

	e = e - s;
	vec4 vert = vec4(s + e * L, 0, 1);

	return vert;
}







#endif


struct S_SampleCurve {
	uint m_buferOffset;
	uint m_num;
};



Inline void f_curve_sampling(){

}

Inline vec2 f_curve_cal_point(S_CurvePoint s_curve, S_CurvePoint e_curve, float gap){
	vec2 v1 = s_curve.value + (s_curve.R_point - s_curve.value) * gap;
	vec2 v2 = s_curve.R_point + (e_curve.L_point - s_curve.R_point) * gap;
	vec2 v3 = e_curve.L_point + (e_curve.value - e_curve.L_point) * gap;
	
	vec2 p1 = (v2 - v1) * gap + v1;
	vec2 p2 = (v3 - v2) * gap + v2;

	return p1 + (p2 - p1) * gap;
}

Inline float f_curve_cal_toLineCenterDis(
	in S_CurvePoint s_curve, 
	in S_CurvePoint e_curve, 
	in vec2 coord, 
	in float step_gap, 
	in float areaSize) 
	{
	vec2 vert0 = f_curve_cal_point(s_curve, e_curve, step_gap*0.03125);
	vec2 vert1 = f_curve_cal_point(s_curve, e_curve, (step_gap+1)*0.03125);
	
	vec2 centerPoint = (vert1 - vert0);
	float radius = length(centerPoint) * 0.5 + areaSize;

	centerPoint = vert0 + centerPoint * 0.5;

	return length(coord - centerPoint) - radius;
}

Inline S_CurvePoint f_curve_cal_pre(in S_CurvePoint s_curve, in S_CurvePoint e_curve){
	S_CurvePoint point = s_curve;
	point.value = s_curve.L_point;
	//point.L_point = point.value - vec_normalize(e_curve.L_point - point.value)*2;
	//point.R_point = point.value+0.001;
	//point.value = s_curve.L_point;
	//point.L_point = point.value;
	//point.R_point = point.value;
	return point;
}

Inline S_CurvePoint f_curve_cal_next(S_CurvePoint e_curve){
	S_CurvePoint point = e_curve;
	point.value = e_curve.R_point;
	return point;
}



DEF_glsl_Cal_CutCircleRadius{
	vec2 size = cp.R_point - cp.L_point;
	return min(cp.value.x, min(abs(size.x * 0.5), abs(size.y * 0.5)));
}





#undef in
#undef out

#endif //TRANSFORM












